import { Injectable, Injector } from '@angular/core';
import { Router } from '@angular/router';
import {
  HttpInterceptor,
  HttpRequest,
  HttpHandler,
  HttpErrorResponse,
  HttpSentEvent,
  HttpHeaderResponse,
  HttpProgressEvent,
  HttpResponse,
  HttpUserEvent,
} from '@angular/common/http';
import {
  SocialService,
  SocialOpenType,
  TokenService,
  DA_SERVICE_TOKEN,
  } from '@delon/auth';
import { Observable, of, throwError } from 'rxjs';
import { mergeMap, catchError } from 'rxjs/operators';
import { NzMessageService } from 'ng-zorro-antd';
import { _HttpClient } from '@delon/theme';
import { environment } from '@env/environment';


/**
 * 默认HTTP拦截器，其注册细节见 `app.module.ts`
 */
@Injectable()
export class DefaultInterceptor implements HttpInterceptor {
  constructor(
    private injector: Injector
    ) {
  }

  get msg(): NzMessageService {
    return this.injector.get(NzMessageService);
  }

  private goTo(url: string) {
    setTimeout(() => this.injector.get(Router).navigateByUrl(url));
  }

  private handleData(
    event: HttpResponse<any> | HttpErrorResponse,
  ): Observable<any> {
    // 可能会因为 `throw` 导出无法执行 `_HttpClient` 的 `end()` 操作
    this.injector.get(_HttpClient).end();
    // 业务处理：一些通用操作
    switch (event.status) {
    case 200:
      // 业务层级错误处理，以下是假定restful有一套统一输出格式（指不管成功与否都有相应的数据格式）情况下进行处理
      // 例如响应内容：
      //  错误内容：{ success: false, message: '非法参数' }
      //  正确内容：{ success: true, data: {  } }
      // 则以下代码片断可直接适用
      //if (event instanceof HttpResponse) {
      //  const body: any = event.body;
      //  if (body && !body.success) {
      //    this.msg.error(body.message);
      //    // 继续抛出错误中断后续所有 Pipe、subscribe 操作，因此：
      //    //this.http.get('/').subscribe(); // 并不会触发
      //    return throwError({});
      //  } else {
      //    // 重新修改 `body` 内容为 `response` 内容，对于绝大多数场景已经无须再关心业务状态码
      //    //return of(new HttpResponse(Object.assign(event, { body: body.response })));
      //    // 或者依然保持完整的格式
      //    return of(event);
      //  }
      //}
      break;
    case 401: // 未登录状态码
      this.goTo('/passport/login');
      break;
    case 403:
    case 404:
    case 500:
      this.goTo(`/${event.status}`);
      break;
    default:
      if (event instanceof HttpErrorResponse) {
        console.warn(
          '未可知错误，大部分是由于后端不支持CORS或无效配置引起',
          event,
        );
        this.msg.error(event.message);
      }
      break;
    }
    return of(event);
  }

  intercept(
    req: HttpRequest<any>,
    next: HttpHandler,
  ): Observable<
    | HttpSentEvent
    | HttpHeaderResponse
    | HttpProgressEvent
    | HttpResponse<any>
    | HttpUserEvent<any>
  > {
    // 统一加上服务端前缀
    let url = req.url;
    if (!url.startsWith('https://') && !url.startsWith('http://')) {
      url = environment.SERVER_URL + url;
    }

    let authReq  = req.clone({
        url: url
      });
   
    return next.handle(authReq).pipe(
      mergeMap((event: any) => {
        if (event instanceof HttpResponse && event.status === 200) {
          return this.handleData(event);
        }
        return of(event);
      }),
      catchError((err: HttpErrorResponse) => this.handleData(err)),
    );
  }
}
